From 9b5e00b3c418d5d6dd0bd193aa974e375669025c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 27 Jun 2015 01:40:04 -0400 Subject: [PATCH] file chooser entry: Capture Escape and emit :hide-entry Make the file chooser entry optionally capture Escape and emit a signal. Make the file chooser widget hide the entry on that signal and go back to the path bar. This gives us a two-level undo: location entry -> path bar -> dialog close. When the location entry is permanently displayed in the header for save mode, we still let the first Escape close the dialog. --- gtk/gtkfilechooserdialog.c | 2 +- gtk/gtkfilechooserentry.c | 31 ++++++++++++++++++++++++++++++- gtk/gtkfilechooserentry.h | 3 ++- gtk/gtkfilechooserwidget.c | 10 +++++++++- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index 189284213b..9fb53e9be7 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -558,7 +558,7 @@ setup_save_entry (GtkFileChooserDialog *dialog) box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); label = gtk_label_new_with_mnemonic (_("_Name")); - entry = _gtk_file_chooser_entry_new (FALSE); + entry = _gtk_file_chooser_entry_new (FALSE, FALSE); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); gtk_container_add (GTK_CONTAINER (box), label); gtk_container_add (GTK_CONTAINER (box), entry); diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 032d19d02c..821a5ee33c 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -31,6 +31,7 @@ #include "gtksizerequest.h" #include "gtkwindow.h" #include "gtkintl.h" +#include "gtkmarshalers.h" typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass; @@ -59,6 +60,7 @@ struct _GtkFileChooserEntry guint current_folder_loaded : 1; guint complete_on_load : 1; guint eat_tabs : 1; + guint eat_escape : 1; guint local_only : 1; }; @@ -69,6 +71,14 @@ enum N_COLUMNS }; +enum +{ + HIDE_ENTRY, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + static void gtk_file_chooser_entry_finalize (GObject *object); static void gtk_file_chooser_entry_dispose (GObject *object); static void gtk_file_chooser_entry_grab_focus (GtkWidget *widget); @@ -157,6 +167,15 @@ _gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class) widget_class->grab_focus = gtk_file_chooser_entry_grab_focus; widget_class->focus_out_event = gtk_file_chooser_entry_focus_out_event; + + signals[HIDE_ENTRY] = + g_signal_new (I_("hide-entry"), + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, + NULL, NULL, + _gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -397,6 +416,13 @@ gtk_file_chooser_entry_tab_handler (GtkWidget *widget, chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget); editable = GTK_EDITABLE (widget); + if (event->keyval == GDK_KEY_Escape && + chooser_entry->eat_escape) + { + g_signal_emit (widget, signals[HIDE_ENTRY], 0); + return TRUE; + } + if (!chooser_entry->eat_tabs) return FALSE; @@ -709,6 +735,7 @@ delete_text_callback (GtkFileChooserEntry *chooser_entry, /** * _gtk_file_chooser_entry_new: * @eat_tabs: If %FALSE, allow focus navigation with the tab key. + * @eat_escape: If %TRUE, capture Escape key presses and emit ::hide-entry * * Creates a new #GtkFileChooserEntry object. #GtkFileChooserEntry * is an internal implementation widget for the GTK+ file chooser @@ -718,12 +745,14 @@ delete_text_callback (GtkFileChooserEntry *chooser_entry, * Returns: the newly created #GtkFileChooserEntry **/ GtkWidget * -_gtk_file_chooser_entry_new (gboolean eat_tabs) +_gtk_file_chooser_entry_new (gboolean eat_tabs, + gboolean eat_escape) { GtkFileChooserEntry *chooser_entry; chooser_entry = g_object_new (GTK_TYPE_FILE_CHOOSER_ENTRY, NULL); chooser_entry->eat_tabs = (eat_tabs != FALSE); + chooser_entry->eat_escape = (eat_escape != FALSE); return GTK_WIDGET (chooser_entry); } diff --git a/gtk/gtkfilechooserentry.h b/gtk/gtkfilechooserentry.h index dd83077097..cf7d8504ba 100644 --- a/gtk/gtkfilechooserentry.h +++ b/gtk/gtkfilechooserentry.h @@ -31,7 +31,8 @@ G_BEGIN_DECLS typedef struct _GtkFileChooserEntry GtkFileChooserEntry; GType _gtk_file_chooser_entry_get_type (void) G_GNUC_CONST; -GtkWidget * _gtk_file_chooser_entry_new (gboolean eat_tab); +GtkWidget * _gtk_file_chooser_entry_new (gboolean eat_tab, + gboolean eat_escape); void _gtk_file_chooser_entry_set_action (GtkFileChooserEntry *chooser_entry, GtkFileChooserAction action); GtkFileChooserAction _gtk_file_chooser_entry_get_action (GtkFileChooserEntry *chooser_entry); diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c index 1c24421883..810948a65e 100644 --- a/gtk/gtkfilechooserwidget.c +++ b/gtk/gtkfilechooserwidget.c @@ -2039,6 +2039,12 @@ location_entry_changed_cb (GtkEditable *editable, reset_location_timeout (impl); } +static void +location_entry_close_clicked (GtkFileChooserWidget *impl) +{ + location_mode_set (impl, LOCATION_MODE_PATH_BAR); +} + static void location_entry_setup (GtkFileChooserWidget *impl) { @@ -2050,6 +2056,8 @@ location_entry_setup (GtkFileChooserWidget *impl) g_signal_connect (priv->location_entry, "changed", G_CALLBACK (location_entry_changed_cb), impl); + g_signal_connect_swapped (priv->location_entry, "hide-entry", + G_CALLBACK (location_entry_close_clicked), impl); _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->local_only); _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->action); @@ -2073,7 +2081,7 @@ location_entry_create (GtkFileChooserWidget *impl) if (!priv->location_entry) { - priv->location_entry = _gtk_file_chooser_entry_new (TRUE); + priv->location_entry = _gtk_file_chooser_entry_new (TRUE, TRUE); location_entry_setup (impl); } } -- 2.30.2